using System;
using System.Collections.Generic;

namespace Mars.ShaderAnalysis
{
    [Serializable]
    public class ShaderKeywordsState
    {
        //public static ShaderKeywordsInfosAsset shaderKeywordsInfosAsset;

        public string keywordString = "";
        public bool isOpen = false;
        [NonSerialized] public List<string> keywords = new List<string>();
        [NonSerialized] public string desc = "";
        [NonSerialized] public bool isCustom = true;

        [NonSerialized] public string keywordTypeString = "";
        [NonSerialized] public bool isLocal = false;
        [NonSerialized] public bool hasFragment = true;
        [NonSerialized] public bool hasVertex = true;
        [NonSerialized] public bool isMultiCompile = false;
        [NonSerialized] public bool isShaderFeature = false;

        [NonSerialized] public int selectKeywordIndex = 0;

        public ShaderKeywordsState(string keywordString, bool isOpen)
        {
            this.keywordString = keywordString;
            this.isOpen = isOpen;
        }

        public ShaderKeywordsState(ShaderKeywordsState shaderKeywordsState)
        {
            keywordString = shaderKeywordsState.keywordString;
            isOpen = shaderKeywordsState.isOpen;
            keywords = new List<string>();
            if (shaderKeywordsState.keywords != null)
            {
                keywords.AddRange(shaderKeywordsState.keywords);
            }

            desc = shaderKeywordsState.desc;
            isCustom = shaderKeywordsState.isCustom;
            keywordTypeString = shaderKeywordsState.keywordTypeString;
            isLocal = shaderKeywordsState.isLocal;
            hasFragment = shaderKeywordsState.hasFragment;
            hasVertex = shaderKeywordsState.hasVertex;
            isMultiCompile = shaderKeywordsState.isMultiCompile;
            isShaderFeature = shaderKeywordsState.isShaderFeature;
            selectKeywordIndex = shaderKeywordsState.selectKeywordIndex;
        }

        /// <summary>
        /// 分析
        /// </summary>
        public void Analysis()
        {
            //Debug.Log(keywordString);
            if (keywords == null)
            {
                keywords = new List<string>();
            }

            keywords.Clear();
            //根据空格拆分keyword
            string[] splits = keywordString.Split(" ");
            HashSet<string> hashSet = new HashSet<string>();
            for (int i = 0; i < splits.Length; i++)
            {
                string str = splits[i];
                if (!string.IsNullOrEmpty(str) && !hashSet.Contains(str) && str != "#pragma")
                {
                    hashSet.Add(str);

                    switch (str)
                    {
                        case "multi_compile_instancing":
                        {
                            keywordTypeString = "multi_compile";
                            isMultiCompile = true;
                            keywords.Add("");
                            keywords.Add("INSTANCING_ON");
                            break;
                        }
                        case "multi_compile_fog":
                        {
                            keywordTypeString = "multi_compile";
                            isMultiCompile = true;
                            keywords.Add("");
                            keywords.Add("FOG_EXP");
                            keywords.Add("FOG_EXP2");
                            keywords.Add("FOG_LINEAR");
                            break;
                        }
                        case "_":
                        case "__":
                        case "___":
                        {
                            keywords.Add("");
                            break;
                        }
                        default:
                        {
                            if (str.StartsWith("multi_compile") || str.StartsWith("shader_feature"))
                            {
                                keywordTypeString = str;
                                isLocal = keywordTypeString.Contains("_local");
                                isMultiCompile = keywordTypeString.StartsWith("multi_compile");
                                isShaderFeature = keywordTypeString.StartsWith("shader_feature");
                                hasFragment = !keywordTypeString.EndsWith("_vertex");
                                hasVertex = !keywordTypeString.EndsWith("_fragment");
                            }
                            else
                            {
                                keywords.Add(str);
                            }

                            break;
                        }
                    }
                }
            }

            if (keywords.Count == 1)
            {
                keywords.Insert(0, "");
            }

            //Debug.Log(keywords.Count);
            //keywords.Sort(CompareKeywords);
            RefreshDesc();
        }

        public void RefreshDesc()
        {
            // if (shaderKeywordsInfosAsset == null)
            // {
            //     shaderKeywordsInfosAsset = AssetDatabase.LoadAssetAtPath<ShaderKeywordsInfosAsset>(TCEditorConstPath.DefaultShaderKeywordsInfosAssetPath);
            // }
            //
            // if (shaderKeywordsInfosAsset != null)
            // {
            //     (desc, isCustom) = shaderKeywordsInfosAsset.GetKeywordDesc(keywordString);
            // }
        }
    }

    public class ShaderGroupByKeyword
    {
        public bool isExpanded = false;
        public string keyword = "";
        public string desc = "";
        public bool isCustom = true;
        public List<ShaderAnalysis> shaderAnalysisList = new List<ShaderAnalysis>();
        private string countString = "";

        public ShaderGroupByKeyword(string keyword, bool isCustom, string desc)
        {
            this.keyword = keyword;
            this.isCustom = isCustom;
            this.desc = desc;
        }

        /// <summary>
        /// 刷新描述
        /// </summary>
        public void RefreshDesc()
        {
            for (int i = 0; i < shaderAnalysisList.Count; i++)
            {
                ShaderKeywordsState state = shaderAnalysisList[i].GetState(keyword);
                if (state != null)
                {
                    state.RefreshDesc();
                }
            }
        }

        /// <summary>
        /// 刷新数值字符串
        /// </summary>
        public string GetCountString(bool forceRefresh = false)
        {
            if (!string.IsNullOrEmpty(countString) && !forceRefresh)
            {
                return countString;
            }

            int totalCount = shaderAnalysisList.Count;
            int useCount = 0;
            for (int i = 0; i < shaderAnalysisList.Count; i++)
            {
                ShaderKeywordsState state = shaderAnalysisList[i].GetState(keyword);
                if (state != null && state.isOpen)
                {
                    useCount++;
                }
            }

            countString = totalCount.ToString("00") + " [<color=#00ff00>" + useCount.ToString("00") + "</color>/<color=#ff0000>" + (totalCount - useCount).ToString("00") + "</color>]";
            return countString;
        }
    }
}